package com.treasure.service.third.utils;

import com.alibaba.fastjson.JSON;
import com.treasure.service.commons.lang.util.DateUtil;
import com.treasure.service.commons.lang.util.IdCreater;
import com.treasure.service.commons.lang.util.SpringContextUtil;
import com.treasure.service.commons.lang.util.StringUtil;
import com.treasure.service.enums.RedisKeys;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;

/**
 * 通过token获取用户基本信息
 * @Auther: panxinwen
 * @Date: 2018/6/10 11:45
 * @Description:
 */
public class TokenConfig {

    private static Logger logger = LoggerFactory.getLogger(TokenConfig.class);

    private static RedisTemplate<String,String> redisTemplate = (RedisTemplate<String, String>) SpringContextUtil.getBean("stringRedisTemplate");

    public static UserToken addToken(UserToken user){

        Long tokenId = IdCreater.getLongId();
        user.setTokenId(tokenId);
//        redisTemplate.opsForHash().put(RedisKeys.TOKEN.build(DateUtil.now(DateUtil.FORMAT_LONG_YMD)), tokenId + "", user.getUserId()+"");
        redisTemplate.opsForHash().put(RedisKeys.TOKEN.build(), tokenId + "", user.getUserId()+"-"+DateUtil.now(DateUtil.FORMAT_LONG_YMD));
        redisTemplate.opsForHash().put(RedisKeys.TOKEN.build("USERINFO"), user.getUserId() + "", JSON.toJSONString(user));

        return user;
    }

    public static void updateTokenIdUserId(Long tokenId,Long userId){
        redisTemplate.opsForHash().put(RedisKeys.TOKEN.build(DateUtil.now(DateUtil.FORMAT_LONG_YMD)), tokenId + "", userId+"");
    }

    public static UserToken updateToken(UserToken user){

        redisTemplate.opsForHash().put(RedisKeys.TOKEN.build("USERINFO"), user.getUserId() + "", JSON.toJSONString(user));

        return user;
    }

    public static UserToken getToken(){

        Object json = redisTemplate.opsForHash().get(RedisKeys.TOKEN.build("USERINFO"),getUserId()+"");

        logger.info("获取用户Token:{}",json);

        if (!StringUtil.isEmpty(json)){
            UserToken token = JSON.parseObject(json.toString(),UserToken.class);
            try {
                token.setNickname(URLDecoder.decode(StringUtil.isEmpty(token.getNickname())?"":token.getNickname(),"utf-8"));
                token.setWNickname(URLDecoder.decode(StringUtil.isEmpty(token.getWNickname())?"":token.getWNickname(),"utf-8"));
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
            return token;

        }

        return new UserToken();
    }
    public static UserToken getToken(Long userId){

        Object json = redisTemplate.opsForHash().get(RedisKeys.TOKEN.build("USERINFO"),userId+"");

        logger.info("获取用户Token:{}",json);

        if (!StringUtil.isEmpty(json)){
            UserToken token = JSON.parseObject(json.toString(),UserToken.class);
            try {
                token.setNickname(URLDecoder.decode(StringUtil.isEmpty(token.getNickname())?"":token.getNickname(),"utf-8"));
                token.setWNickname(URLDecoder.decode(StringUtil.isEmpty(token.getWNickname())?"":token.getWNickname(),"utf-8"));
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
            return token;

        }

        return new UserToken();
    }
    public static Long getUserId(){

        ServletRequestAttributes sra = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = sra.getRequest();

        Cookie cookie = CookiesUtil.getCookieByName(request,"token");
        if(cookie==null){
            return null;
//            return 6416625104322560L;
        }
        logger.info("获取用户cookie:{}",cookie.getValue());

        Object json = redisTemplate.opsForHash().get(RedisKeys.TOKEN.build(DateUtil.now(DateUtil.FORMAT_LONG_YMD)),cookie.getValue());

        logger.info("获取用户id:{}",json);

        return StringUtil.isEmpty(json)?null:Long.parseLong(json.toString());
    }
    public static Long getCharacterEncoding(){

        ServletRequestAttributes sra = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = sra.getRequest();

        Cookie cookie = CookiesUtil.getCookieByName(request,"token");

        Object json = redisTemplate.opsForHash().get(RedisKeys.TOKEN.build(DateUtil.now(DateUtil.FORMAT_LONG_YMD)),cookie.getValue());


        return StringUtil.isEmpty(json)?null:Long.parseLong(json.toString());
    }

    public static UserToken getTokenByHeader(){

        ServletRequestAttributes sra = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = sra.getRequest();
        String token =request.getHeader("token");

        logger.info("获取header中的tokenid==={}",token);

        if (StringUtil.isEmpty(token)){
            return null;
        }

//        Object json = redisTemplate.opsForHash().get(RedisKeys.TOKEN.build(DateUtil.now(DateUtil.FORMAT_LONG_YMD)),token);
        Object json = redisTemplate.opsForHash().get(RedisKeys.TOKEN.build(),token);

        if (StringUtil.isNotEmpty(json)){
            String[] j = (json+"").split("-");
            int n = Integer.parseInt(DateUtil.now(DateUtil.FORMAT_LONG_YMD));
            int l = Integer.parseInt(j[1]);
            if (n-l>7){
                redisTemplate.opsForHash().delete(RedisKeys.TOKEN.build(),token);
                return null;
            }
        }

        logger.info("获取用户id==={}",json);

        Object userinfo = redisTemplate.opsForHash().get(RedisKeys.TOKEN.build("USERINFO"),(json+"").split("-")[0]);

        if (!StringUtil.isEmpty(userinfo)){
            UserToken userToken = JSON.parseObject(userinfo.toString(),UserToken.class);
            try {
                userToken.setNickname(URLDecoder.decode(StringUtil.isEmpty(userToken.getNickname())?"":userToken.getNickname(),"utf-8"));
                userToken.setWNickname(URLDecoder.decode(StringUtil.isEmpty(userToken.getWNickname())?"":userToken.getWNickname(),"utf-8"));
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
            return userToken;

        }

        return null;
    }
    public static UserToken getUserByToken(String token){

        logger.info("获取用户token:{}",token);

        if (StringUtil.isEmpty(token)){
            return null;
        }

        Object json = redisTemplate.opsForHash().get(RedisKeys.TOKEN.build(DateUtil.now(DateUtil.FORMAT_LONG_YMD)),token);

        logger.info("获取用户id:{}",json);

        Object userinfo = redisTemplate.opsForHash().get(RedisKeys.TOKEN.build("USERINFO"),json+"");

        if (!StringUtil.isEmpty(userinfo)){
            UserToken userToken = JSON.parseObject(userinfo.toString(),UserToken.class);
            try {
                userToken.setNickname(URLDecoder.decode(StringUtil.isEmpty(userToken.getNickname())?"":userToken.getNickname(),"utf-8"));
                userToken.setWNickname(URLDecoder.decode(StringUtil.isEmpty(userToken.getWNickname())?"":userToken.getWNickname(),"utf-8"));
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
            return userToken;

        }

        return null;
    }

    public static <T> void setAttribute(SessionKey key, T t) {
        getSession().setAttribute(key.name(), t);
    }

    public static <T> T getAttribute(SessionKey key) {
        return (T) getSession().getAttribute(key.name());
    }

    public static void removeAttribute(SessionKey key) {
        getSession().removeAttribute(key.name());
    }

    public static HttpSession getSession() {
        return ((ServletRequestAttributes)RequestContextHolder.currentRequestAttributes()).getRequest().getSession();
    }

    public static String getUserName() {
        return getUser().getUserName();
    }

    public static UserToken getUser() {
        return getAttribute(SessionKey.TOKEN);
    }

    public static boolean isLogin() {
        return getUser() != null;
    }

}
